﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Windows.Media.Imaging;
using BrainTechLLC;
using BrainTechLLC.ThreadSafeObjects;
using System.Windows.Media;
using System.IO;

namespace BrainTechLLC.ImageOperatorsNonAForgeDependent
{
    public static partial class ImageSourceCreation
    {
        public static ImageSource CreateImageSourceFromBitmap(this Bitmap bm, byte[] bytes, int width, int height)
        {
            if (bm == null)
            {
                if (bytes != null)
                {
                    try
                    {
                        bm = System.Drawing.Image.FromStream(new MemoryStream(bytes), true, false) as Bitmap;
                        return bm.CreateImageSourceFromBitmap(bytes);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                        return null;
                    }
                }
                else
                {
                    return null;
                }
            }
            else
            {
                int attempt = 0;

            TryAgain:
                try
                {
                    if (width == 0)
                    {
                        width = bm.Width;
                    }
                    if (height == 0)
                    {
                        height = bm.Height;
                    }
                    double dpiX = bm.HorizontalResolution;
                    double dpiY = bm.VerticalResolution;
                    BitmapPalette palette = null;
                    System.Windows.Media.PixelFormat pixelFormat = bm.PixelFormat.GetMediaPixelFormat();
                    Timing.BeginTiming();

                    var data = bm.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bm.PixelFormat);
                    try
                    {
                        int stride = data.Stride;
                        int bufferSize = (height * stride);
                        BitmapSource bmSource = BitmapSource.Create(width, height, dpiX, dpiY, pixelFormat, palette, data.Scan0, bufferSize, data.Stride);
                        bmSource.Freeze();
                        return bmSource;
                    }
                    catch (Exception e)
                    {
                        //#if CONSOLE_WRITELINE_EVERYTHING
                        Console.WriteLine(e.ToString());
                        //#endif
                        Debug.WriteLine(e.ToString());
                        Debug.Assert(false);
                    }
                    finally
                    {
                        bm.UnlockBits(data);
                        Timing.EndTiming((d) => AllStats.GetInstance().AddTime("AverageImageSourceTime", d));
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    if (attempt == 0 && bytes != null)
                    {
                        // attempt to create a bitmap from the byte array, then try creating the image source again
                        attempt++;
                        bm = System.Drawing.Image.FromStream(new MemoryStream(bytes), true, false) as Bitmap;
                        goto TryAgain;
                    }
                    Debug.WriteLine(ex.ToString());
                    Debug.Assert(false);
                    return null;
                }
            }

            return null;
        }

        public static ImageSource CreateImageSourceFromBitmap(this Bitmap bm, byte[] bytes)
        {
            return CreateImageSourceFromBitmap(bm, bytes, 0, 0);
        }
    }
}
